#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

import os
import xml.etree.ElementTree as ET

from gaussdbt.commons.const import log, WHITE_LIST, AREA_PARENT_PATH, AGENT_CFG_FILE
from gaussdbt.commons.decorator_common import function_debug_log
from common.common import execute_cmd, check_command_injection
from common.const import CMDResult


@function_debug_log
def get_database_max_protect_mode(db_suer):
    cmd = f"su - {db_suer} -c 'zsql / as sysdba -q -c \"select PROTECTION_MODE from dv_database;\"'"
    return_code, std_out, std_err = execute_cmd(cmd)
    if return_code != CMDResult.SUCCESS:
        log.error(f"Fail to exec cmd check database protection mode, error: {std_err}")
        return False
    if "MAXIMUM_PROTECTION" in std_out:
        log.info("The Maximum Protection mode is enabled.")
        return True
    log.info("The Maximum Protection mode is disable.")
    return False


def gaussdbt_check_user_name_and_injection(param: str):
    """
    检测用户名是否为空并判断是否有特殊字符
    :param : 用户名
    :return: bool
    """
    if not param:
        return True
    return check_command_injection(param)


def check_if_path_in_cache(file_path: str, cache_path: str):
    if os.path.islink(file_path) or os.path.islink(cache_path):
        log.error("Path includes link!")
        return False
    abs_file = os.path.realpath(file_path)
    abs_cache = os.path.realpath(cache_path)
    if abs_file.startswith(abs_cache) and abs_file.startswith(WHITE_LIST):
        return True
    log.error(f"File not in cache! path: {file_path}")
    return False


def get_area_parent_path():
    """
    获取挂载父路径。
    如果AGENT_CFG_FILE文件不存在或不存在linux_mount_public_path字段，则使用默认路径AREA_PARENT_PATH，
    否则从该文件中解析出路径。

    return:
    返回解析出的路径或者默认路径。
    """
    parent_path = AREA_PARENT_PATH
    if not os.path.exists(AGENT_CFG_FILE):
        return parent_path
    tree = ET.parse(AGENT_CFG_FILE)
    root = tree.getroot()
    if root:
        path_nodes = root.findall('.//Mount/linux_mount_public_path')
        for path_node in path_nodes:
            path = path_node.get('value')
            if path:
                path = path.rstrip("/")
                log.info(f"Use {path} from agent_xml.cfg.")
                return path
    log.info(f"Use default path {parent_path}.")
    return parent_path

